/********************************************************************************/
/*		DecodedStructs.h: headerfile for module containing:		*/
/*		    setOpcode, setRegisters, setReg, setFloat			*/
/********************************************************************************/

#ifndef DECODEDSTRUCTS_H
#define DECODEDSTRUCTS_H

#define STR_SIZE 10


/* Type Definitions */

typedef struct r RTYPE;
typedef struct i ITYPE;
typedef struct j JTYPE;
typedef struct b17 BIT17;
typedef struct d DUMMY;

/*Output Instruction structure */
typedef struct DeInst DECODED;

typedef struct Instructionlist ILIST;
typedef struct InstructionEntry IENTRY;


struct Instructionlist
	{
	unsigned int  Length; /* Length of the list*/
	/*unsigned int NumberInstructions:*/
	IENTRY *First; /* pointer to the first entry, or NULL */
	IENTRY *Last; /* pointer to the last entry, or NULL  */
	};

struct InstructionEntry
	{
	ILIST  *List;   /* pointer to the list which this entry belongs to */
	IENTRY *Next;   /* pointer to the next entry, or NULL */
	IENTRY *Prev;   /* pointer to the previous entry, or NULL */
	unsigned int instruction;  /* Instruction */
	DECODED *DeInstruction;
	};



/* R Type Structure */
struct r
{
	unsigned int funct : 6;
    	unsigned int fd : 5; 
    	unsigned int rd : 5;
    	unsigned int rt : 5;
    	unsigned int rs : 5;
    	unsigned int opcode : 6;
};

/* I Type Structure */
struct i
{
        unsigned int offset : 16; 
        unsigned int tal: 2;
        unsigned int cc : 3;
        unsigned int rs : 5;
        unsigned int opcode : 6;
};

/* J Type Structure */
struct j
{
        unsigned int target : 26;
        unsigned int opcode : 6;
};

struct b17
{
        unsigned int baz : 16;
        unsigned int a : 1;
        unsigned int foo : 15;
};

struct d
{
	unsigned int pad : 26;
	unsigned int opcode : 6;
};

/* Output Structure */
struct DeInst
{
        char *opcode;
        char *reg1;
        char *reg2;
        char *reg3;
};

/* This union will be populated with the RTYPE, ITYPE, and JTYPE */
/* structs for quick dividing of bits */
typedef union Instruction 
{
	unsigned int instruction;
	DUMMY D;
  	RTYPE R;
  	ITYPE I;
    	JTYPE J;
    	BIT17 B17;
}INSTU;

/* DECODED memory handling functions */

/* Allocates the memory necessary for the decoded instruction fields */
DECODED *CreateDeInst();

/*Frees DeInt struct and its members */
void DeleteDeInst(DECODED *DeInst);
/* setOpcode Function: Takes in an instruction union and a decoded struct and	*/
/* modifies the value of the opcode string pointer to reflect the mnemonic 	*/
/* associated with the instruction in the union. The opcode string is set to \0 */

void setOpcode(INSTU u, DECODED *d);

/* setRegisters Function: Formerly called disassembler, this function is made 	*/
/* for the sake of modularization and readability. It makes more sense for this */
/* acitivity to be used on the same level as setOpcode. In this way, the 	*/
/* disassembler function sent to the larger group will be simpler.		*/

/* setRegisters takes in an instruction union and a decoded struct and modifies */
/* all three of the register strings to reflect the order they should appear in */
/* according to the opcode, and to reflect the conventional names for the regs	*/

void setRegisters(INSTU u, DECODED *d);

/* setReg Function: Takes in an integer reflecting the value of the register, 	*/
/* and a string into which the conventional name for the register will be stored*/

void setReg(int i, char *c);

/* setFloat Function: The same as setReg except this function is for the float	*/
/* registers used by the coprocessors						*/

void setFloat(int i, char *c);

#endif
